//
//  TestCaseRun.m
//  WiteBox
//
//  Created by John Blanco on 6/27/09.
//  Copyright 2009 Effective UI. All rights reserved.
//

#import "TestCaseRun.h"

#import <objc/objc-runtime.h>

#import "TestCase.h"
#import "TestRun.h"
#import "AssertionException.h"

@implementation TestCaseRun

- (id)initWithClass:(Class)aClass {
	self = [super init];
	
	if (self) {
		testCaseClass = aClass;
		passingTests = 0;
		failingTests = 0;
		executedTests = 0;
		testRuns = [[NSMutableArray alloc] init];
	}
	
	return self;
}

- (void)dealloc {
	[testRuns release];
	[super dealloc];
}

#pragma mark -

- (void)addTestRun:(TestRun *)testRun {
	[testRuns addObject:testRun];
}

- (void)runTests {
	// instantiate test case
	TestCase *testCase = (TestCase *)class_createInstance(testCaseClass, 0);
	
	if ([testCase isEnabled]) {
		// set up
		[testCase setUp];
		
		for (TestRun *iTestRun in testRuns) {
			// pool
			NSAutoreleasePool *newPool = [[NSAutoreleasePool alloc] init];
			
			SEL testMethod = [iTestRun testMethod];
			double startTime = [[NSDate date] timeIntervalSince1970];
			
			// set up test
			[testCase setUpTest:testMethod];
			
			@try {
				[testCase performSelector:testMethod];
				iTestRun.isPassingTest = YES;
				passingTests++;
			} @catch (AssertionException *assertException) {
				iTestRun.exception = assertException;
				iTestRun.isPassingTest = NO;
				failingTests++;
			} @catch (NSException *exception) {
				iTestRun.exception = exception;
				iTestRun.isPassingTest = NO;
				failingTests++;
			} @catch (NSError *error) {
				iTestRun.exception = [NSException exceptionWithName:@"ERROR" reason:[error description] userInfo:nil];
				iTestRun.isPassingTest = NO;
				failingTests++;
			} @finally {
				iTestRun.isTestComplete = YES;
				executedTests++;
			}
			
			// tear down test
			[testCase tearDownTest:testMethod];
			
			// log durations
			iTestRun.duration = [[NSDate date] timeIntervalSince1970] - startTime;
			
			// pool
			[newPool release];			
		}
	}
	
	// tear down
	[testCase tearDown];
}

- (Class)testCaseClass {
	return testCaseClass;
}

- (NSString *)testCaseClassName {
	return [NSString stringWithFormat:@"%s", class_getName(testCaseClass)];
}

- (NSArray *)testRuns {
	return [NSArray arrayWithArray:testRuns];
}

- (NSInteger)passingTests {
	return passingTests;
}

- (NSInteger)failingTests {
	return failingTests;
}

- (NSInteger)executedTests {
	return executedTests;
}

- (NSInteger)totalTests {
	return [testRuns count];
}

- (BOOL)isCompleted {
	return (executedTests > 0);
}

- (double)durationOfAllRuns {
	double totalDuration = 0.00;
	
	for (TestRun *iTestRun in testRuns) {
		totalDuration += iTestRun.duration;
	}
	
	return totalDuration;
}

@end
